package com.example.ffepeg.ffeImg;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;

public class FFMpegHandler {
    //时长绝对相等
    public static void main(String[] args) {
        String videoFile = "D:\\javaXM\\FFEpeg\\src\\main\\resources\\file\\3652234199995.mp4"; //6秒
        String audioFile = "D:\\javaXM\\FFEpeg\\src\\main\\resources\\file\\cvadsfa.wav"; //30秒
        String outputFile = "D:\\javaXM\\FFEpeg\\src\\main\\resources\\out\\output.mp4";

        try {
            // 获取视频和音频的时长
            float videoDuration = getMediaDuration(videoFile);
            float audioDuration = getMediaDuration(audioFile);

            if (videoDuration > audioDuration) {
                // 视频大于音频，使用音频时长
                executeCommand(new String[]{"ffmpeg", "-i", videoFile, "-i", audioFile, "-map", "0:v", "-map", "1:a", "-shortest", "-to", String.valueOf(audioDuration), outputFile});
            } else {
                // 音频大于视频，计算需要重复视频几次来匹配音频时长
                int repeatCount = (int) Math.ceil(audioDuration / videoDuration);

                StringBuilder fileListContent = new StringBuilder();
                for (int i = 0; i < repeatCount; i++) {
                    fileListContent.append("file '").append(videoFile).append("'\n");
                }
                String fileListPath = "input.txt";
                Files.write(Paths.get(fileListPath), fileListContent.toString().getBytes());

                // 使用concat模式合并视频片段并匹配音频时长
                executeCommand(new String[]{"ffmpeg", "-f", "concat", "-safe", "0", "-i", fileListPath, "-i", audioFile, "-map", "0:v", "-map", "1:a", "-vsync", "vfr", "-t", String.valueOf(audioDuration), outputFile});
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static float getMediaDuration(String mediaFile) throws Exception {
        ProcessBuilder pb = new ProcessBuilder("ffprobe", "-v", "error", "-show_entries", "format=duration", "-of", "default=noprint_wrappers=1:nokey=1", mediaFile);
        Process process = pb.start();
        BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
        String line = reader.readLine();
        return Float.parseFloat(line);
    }

    private static void executeCommand(String[] command) throws Exception {
        ProcessBuilder pb = new ProcessBuilder(command);
        pb.inheritIO(); // 继承父进程的标准输入、输出和错误流
        Process process = pb.start();
        if (process.waitFor() != 0) {
            throw new RuntimeException("Failed to execute command: " + String.join(" ", command));
        }
    }
}
